package com.info.zhiduoduo.pay.sdk.zhaoshangbank.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.info.zhiduoduo.common.configs.ZhaoShangPayConfig;
import com.info.zhiduoduo.common.constants.StatusMsg;
import com.info.zhiduoduo.common.exception.SmartException;
import com.info.zhiduoduo.common.utils.StringUtil;
import com.info.zhiduoduo.pay.formbean.zhaoshangtradebulter.QuerySubLedgerBalanceFormBean;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.model.common.HeadReqDTO;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.model.common.HeadRespDTO;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.model.common.RequestDTO;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.model.common.ResponseDTO;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.model.request.tradebulter.QuerySubLedgerBalanceReqDTO;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.model.request.tradebulter.detail.QuerySubLedgerBalanceInfo;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.model.response.tradebulter.*;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.model.response.tradebulter.detail.QuerySubLedgerBalanceResult;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.model.response.tradebulter.detail.QuerySubLedgerBalanceSequel;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.util.HttpUtils;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.util.ZsPayUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;

/**
 * API 文档：招商银行云直联开发指南.docx
 */
@Slf4j
@Service
public class ZhaoshangTradeButlerApiService {

	@Resource
	ZhaoShangPayConfig zhaoShangPayConfig;

	/**
	 * 5.5.2.1新增记账子单元 NTDMAADD
	 *
	 * @param dto
	 * @return
	 */
	public ResponseDTO<?> createSubLedger(RequestDTO<?> dto) {
		log.info("新增记账子单元-请求对象：" + JSON.toJSONString(dto));
		String result = pushPost(dto.toJson(), zhaoShangPayConfig.getUserId(), dto.getHead().getFuncode());
		if (StringUtil.isEmpty(result)) {
			log.error("新增记账子单元-请求返回为空（网络异常）！");
			throw SmartException.of(StatusMsg.StatusMsg_473);
		}
		//将结果转为json
		try {
			JSONObject object = JSON.parseObject(result);
			log.info("新增记账子单元-请求返回结果:" + object.toString());
			return object.getObject("response", new TypeReference<ResponseDTO<?>>() {
			});
		} catch (Exception e) {
			log.error("新增记账子单元-请求结果解析失败");
			throw SmartException.of(StatusMsg.StatusMsg_474);
		}
	}

	/**
	 * 5.5.2.4 关闭记账子单元NTDMADLT
	 *
	 * @param dto
	 * @return
	 */
	public ResponseDTO<?> deleteSubLedger(RequestDTO<?> dto) {
		log.info("关闭记账子单元-请求对象：" + JSON.toJSONString(dto));
		String result = pushPost(dto.toJson(), zhaoShangPayConfig.getUserId(), dto.getHead().getFuncode());
		if (StringUtil.isEmpty(result)) {
			log.error("关闭记账子单元-请求返回为空（网络异常）！");
			throw SmartException.of(StatusMsg.StatusMsg_473);
		}
		//将结果转为json
		try {
			JSONObject object = JSON.parseObject(result);
			log.info("关闭记账子单元-请求返回结果:" + object.toString());
			return object.getObject("response", new TypeReference<ResponseDTO<?>>() {
			});
		} catch (Exception e) {
			log.error("关闭记账子单元-请求结果解析失败");
			throw SmartException.of(StatusMsg.StatusMsg_474);
		}
	}

	/**
	 * 修改记账子单元NTDMAMNT
	 *
	 * @param dto
	 * @return
	 */
	public ResponseDTO<?> updateSubLedger(RequestDTO<?> dto) {
		log.info("修改记账子单元-请求对象：" + JSON.toJSONString(dto));
		String result = pushPost(dto.toJson(), zhaoShangPayConfig.getUserId(), dto.getHead().getFuncode());
		if (StringUtil.isEmpty(result)) {
			log.error("修改记账子单元-请求返回为空（网络异常）！");
			throw SmartException.of(StatusMsg.StatusMsg_473);
		}
		//将结果转为json
		try {
			JSONObject object = JSON.parseObject(result);
			log.info("修改记账子单元-请求返回结果:" + object.toString());
			return object.getObject("response", new TypeReference<ResponseDTO<?>>() {
			});
		} catch (Exception e) {
			log.error("修改记账子单元-请求结果解析失败");
			throw SmartException.of(StatusMsg.StatusMsg_474);
		}
	}

	/**
	 * 5.5.2.15查询记账子单元余额NTDMABAL
	 *
	 * @param dto
	 * @return
	 */
	public ResponseDTO<QuerySubLedgerBalanceRespDTO> querySubLedgerBalance(RequestDTO<?> dto) {
		log.info("查询记账子单元余额-请求对象：" + JSON.toJSONString(dto));
		String result = pushPost(dto.toJson(), zhaoShangPayConfig.getUserId(), dto.getHead().getFuncode());
		if (StringUtil.isEmpty(result)) {
			log.error("查询记账子单元余额-请求返回为空（网络异常）！");
			throw SmartException.of(StatusMsg.StatusMsg_473);
		}
		//将结果转为json
		try {
			JSONObject object = JSON.parseObject(result);
			log.info("查询记账子单元余额-请求返回结果:" + object.toString());
			return object.getObject("response", new TypeReference<ResponseDTO<QuerySubLedgerBalanceRespDTO>>() {
			});
		} catch (Exception e) {
			log.error("查询记账子单元余额-请求结果解析失败");
			throw SmartException.of(StatusMsg.StatusMsg_474);
		}
	}

	/**
	 * 5.5.2.15查询记账子单元余额NTDMABAL
	 *
	 * @param
	 * @return
	 */
	public ResponseDTO<QuerySubLedgerBalanceRespDTO> querySubLedgerBalance(QuerySubLedgerBalanceFormBean formBean) {

		ResponseDTO<QuerySubLedgerBalanceRespDTO> returnResponseDTO = new ResponseDTO<>();

		List<QuerySubLedgerBalanceResult> list = Lists.newArrayList();
		String rsv50z = "";
		//构建head信息
		HeadReqDTO headReqDTO = HeadReqDTO.of(zhaoShangPayConfig.getQuerySubLedgerBalance(), zhaoShangPayConfig.getUserId());

		do {
			//构建body中子帐本信息
			List<QuerySubLedgerBalanceInfo> querySubLedgerBalanceInfos = QuerySubLedgerBalanceInfo.ofList(formBean, rsv50z);
			//构建body
			QuerySubLedgerBalanceReqDTO reqDTO = new QuerySubLedgerBalanceReqDTO().setNtdmabalx(querySubLedgerBalanceInfos);
			RequestDTO<?> dto = RequestDTO.of(headReqDTO, reqDTO);

			log.info("查询记账子单元余额-请求对象：" + JSON.toJSONString(dto));
			String result = pushPost(dto.toJson(), zhaoShangPayConfig.getUserId(), dto.getHead().getFuncode());
			if (StringUtil.isEmpty(result)) {
				log.error("查询记账子单元余额-请求返回为空（网络异常）！");
				throw SmartException.of(StatusMsg.StatusMsg_473);
			}

			//将结果转为json
			try {
				JSONObject object = JSON.parseObject(result);
				log.info("查询记账子单元余额-请求返回结果:" + object.toString());

				ResponseDTO<QuerySubLedgerBalanceRespDTO> responseDTO = object.getObject("response", new TypeReference<ResponseDTO<QuerySubLedgerBalanceRespDTO>>() {});
				//获取head信息
				HeadRespDTO head = responseDTO.getHead();
				returnResponseDTO.setHead(head);
				if (null == head) {
					log.error("查询记账子单元的余额信息-失败！失败原因：head为空");
					throw SmartException.of(StatusMsg.StatusMsg_476);
				}
				if (!"SUC0000".equals(head.getResultcode())) {
					log.error("查询记账子单元的余额信息-失败！失败原因：" + head.getResultmsg());
					throw SmartException.of(StatusMsg.StatusMsg_477);
				}
				//获取body信息
				QuerySubLedgerBalanceRespDTO body = responseDTO.getBody();
				if (null == body) {
					log.error("查询记账子单元余额-失败！失败原因：body为空");
					break;
				}
				//获取结果
				List<QuerySubLedgerBalanceResult> ntdmtlstz = body.getNtdmabalz();
				if (CollectionUtils.isNotEmpty(ntdmtlstz)) {
					list.addAll(ntdmtlstz);
				}
				// 设置续传值
				List<QuerySubLedgerBalanceSequel> ntdmabalx = body.getNtdmabalx();
				if (CollectionUtils.isNotEmpty(ntdmabalx)) {
					// Renew the subsequent keyword.
					rsv50z = ntdmabalx.get(0).getRsv50z();
				} else {
					// Means there are no more subsequent records, set the variable "rsv50z" to an empty string.
					rsv50z = "";
				}

				QuerySubLedgerBalanceRespDTO respDTO = new QuerySubLedgerBalanceRespDTO();
				respDTO.setNtdmabalz(list);
				returnResponseDTO.setBody(respDTO);

			} catch (Exception e) {
				log.error("查询记账子单元余额-请求结果解析失败");
				throw SmartException.of(StatusMsg.StatusMsg_474);
			}
		}
		// Keep retrieving more records from the API if "rsv50z" is not empty.
		while (StringUtil.isNotEmpty(rsv50z));

		return returnResponseDTO;
	}

	/**
	 * 5.5.2.3 查询记账子单元信息NTDMALST
	 *
	 * @param dto
	 * @return
	 */
	public ResponseDTO<QuerySubLedgerStatusRespDTO> querySubLedgerStatus(RequestDTO<?> dto) {
		log.info("查询记账子单元信息-请求对象：" + JSON.toJSONString(dto));
		String result = pushPost(dto.toJson(), zhaoShangPayConfig.getUserId(), dto.getHead().getFuncode());
		if (StringUtil.isEmpty(result)) {
			log.error("查询记账子单元信息-请求返回为空（网络异常）！");
			throw SmartException.of(StatusMsg.StatusMsg_473);
		}
		//将结果转为json
		try {
			JSONObject object = JSON.parseObject(result);
			log.info("查询记账子单元信息-请求返回结果:" + object.toString());
			return object.getObject("response", new TypeReference<ResponseDTO<QuerySubLedgerStatusRespDTO>>() {
			});
		} catch (Exception e) {
			log.error("查询记账子单元信息-请求结果解析失败");
			throw SmartException.of(StatusMsg.StatusMsg_474);
		}
	}

	/**
	 * 5.5.2.21记账子单元内部转账NTDMATRX
	 *
	 * @param dto
	 * @return
	 */
	public ResponseDTO<SubLedgerPayRespDTO> subLedgerPay(RequestDTO<?> dto) {
		log.info("记账子单元内部转账-请求对象：" + JSON.toJSONString(dto));
		String result = pushPost(dto.toJson(), zhaoShangPayConfig.getUserId(), dto.getHead().getFuncode());
		if (StringUtil.isEmpty(result)) {
			log.error("记账子单元内部转账-请求返回为空（网络异常）！");
			throw SmartException.of(StatusMsg.StatusMsg_473);
		}
		//将结果转为json
		try {
			JSONObject object = JSON.parseObject(result);
			log.info("记账子单元内部转账-请求返回结果:" + object.toString());
			return object.getObject("response", new TypeReference<ResponseDTO<SubLedgerPayRespDTO>>() {
			});
		} catch (Exception e) {
			log.error("记账子单元内部转账-请求结果解析失败");
			throw SmartException.of(StatusMsg.StatusMsg_474);
		}
	}

	/**
	 * 5.5.1.2.8记账子单元退款经办NTOPRDMR
	 *
	 * @param dto
	 * @return
	 */
	public ResponseDTO<SubLedgerRefundRespDTO> subLedgerRefund(RequestDTO<?> dto) {
		log.info("记账子单元退款经办-请求对象：" + JSON.toJSONString(dto));
		String result = pushPost(dto.toJson(), zhaoShangPayConfig.getUserId(), dto.getHead().getFuncode());
		if (StringUtil.isEmpty(result)) {
			log.error("记账子单元退款经办-请求返回为空（网络异常）！");
			throw SmartException.of(StatusMsg.StatusMsg_473);
		}
		//将结果转为json
		try {
			JSONObject object = JSON.parseObject(result);
			log.info("记账子单元退款经办-请求返回结果:" + object.toString());
			return object.getObject("response", new TypeReference<ResponseDTO<SubLedgerRefundRespDTO>>() {
			});
		} catch (Exception e) {
			log.error("记账子单元退款经办-请求结果解析失败");
			throw SmartException.of(StatusMsg.StatusMsg_474);
		}
	}

	/**
	 * 5.5.2.13查询记账子单元当天交易NTDMTLST
	 *
	 * @param dto
	 * @return
	 */
	public ResponseDTO<QuerySubLedgerTradeRespDTO> querySubLedgerTrade(RequestDTO<?> dto) {
		log.info("查询记账子单元当天交易-请求对象：" + JSON.toJSONString(dto));
		String result = pushPost(dto.toJson(), zhaoShangPayConfig.getUserId(), dto.getHead().getFuncode());
		if (StringUtil.isEmpty(result)) {
			log.error("查询记账子单元当天交易-请求返回为空（网络异常）！");
			throw SmartException.of(StatusMsg.StatusMsg_473);
		}
		//将结果转为json
		try {
			JSONObject object = JSON.parseObject(result);
			log.info("查询记账子单元当天交易-请求返回结果:" + object.toString());
			return object.getObject("response", new TypeReference<ResponseDTO<QuerySubLedgerTradeRespDTO>>() {
			});
		} catch (Exception e) {
			log.error("查询记账子单元当天交易-请求结果解析失败");
			throw SmartException.of(StatusMsg.StatusMsg_474);
		}
	}

	/**
	 * 5.5.2.14查询记账子单元历史交易NTDMTHLS
	 *
	 * @param dto
	 * @return
	 */
	public ResponseDTO<QuerySubLedgerHistoryTradeRespDTO> querySubLedgerHistoryTrade(RequestDTO<?> dto) {
		log.info("查询记账子单元历史交易-请求对象：" + JSON.toJSONString(dto));
		String result = pushPost(dto.toJson(), zhaoShangPayConfig.getUserId(), dto.getHead().getFuncode());
		if (StringUtil.isEmpty(result)) {
			log.error("查询记账子单元历史交易-请求返回为空（网络异常）！");
			throw SmartException.of(StatusMsg.StatusMsg_473);
		}
		//将结果转为json
		try {
			JSONObject object = JSON.parseObject(result);
			log.info("查询记账子单元历史交易-请求返回结果:" + object.toString());
			return object.getObject("response", new TypeReference<ResponseDTO<QuerySubLedgerHistoryTradeRespDTO>>() {
			});
		} catch (Exception e) {
			log.error("查询记账子单元历史交易-请求结果解析失败");
			throw SmartException.of(StatusMsg.StatusMsg_474);
		}
	}

	public String pushPost(JSONObject jsonObject, String UID, String funcode) {
		// 发送请求
		try {
			String URL = zhaoShangPayConfig.getUrl();
			String bankpubkey = zhaoShangPayConfig.getBankPubKey();
			String privkey = zhaoShangPayConfig.getPrivkey();
			String sm4key = zhaoShangPayConfig.getSm4key();
			return ZsPayUtil.doProcess(new GsonBuilder().create().fromJson(jsonObject.toJSONString(), JsonObject.class), UID, URL, funcode, bankpubkey, privkey, sm4key);
		} catch (Exception e) {
			log.error("招商记账子单元接口请求异常", e);
		}
		return null;
	}

//	private String pushPost(JSONObject jsonObject, String userId, String funcode) {
//		// 发送请求
//		HashMap<String, String> map = new HashMap<>();
//		map.put("UID", userId);
//		// map.put("FUNCODE", funcode);
//		map.put("DATA", jsonObject.toJSONString());
//		try {
//			return HttpUtils.doPostForm(zhaoShangPayConfig.getUrl(), map);
//		} catch (Exception e) {
//			log.error("招商接口请求异常", e);
//		}
//		return null;
//	}
}
